package ui.tp3.modelo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Random;

public class Matriz implements Serializable {

	/******* VARIABLES **********/

	private Coordenada limite;
	private ArrayList<ArrayList<Posicionable>> celdas = new ArrayList<ArrayList<Posicionable>>();

	/*************** GETTERS Y SETTERS *************/
	public Coordenada getLimite() {
		return limite;
	}

	public void setLimite(Coordenada limite) {
		this.limite = limite;
	}

	public void setCeldas(ArrayList<ArrayList<Posicionable>> celdas) {
		this.celdas = celdas;
	}

	public ArrayList<ArrayList<Posicionable>> getCeldas() {
		return celdas;
	}

	/********** CONSTRUCTOR ****************/

	/**
	 * Este constructor recibe dos enteros
	 * 
	 * el primero o x es el numero de columnas de la matriz el segundo o y es el
	 * numero de filas de la matriz
	 * 
	 * */

	public Matriz(int limiteX, int limiteY) {

		this.limite = new Coordenada(limiteX, limiteY);
		this.generarCeldas(limiteX, limiteY);

	}
	
	public Matriz(){}
	

	/**
	 * Este metodo genera las celdas dentro de la matriz
	 * 
	 * @param nrosColumna
	 * @param nrosFila
	 */

	private void generarCeldas(int nrosColumna, int nrosFila) {
		for (int i = 0; i < nrosColumna; i++) {
			ArrayList<Posicionable> fila = new ArrayList<Posicionable>();

			for (int f = 0; f < nrosFila; f++) {
				fila.add(new Celda());
			}

			this.celdas.add(fila);
		}

	}

	/**
	 * Este metodo ubica un elemento del tipo posicionable en una coordenada,
	 * ambos dos pasados por parametro
	 * 
	 * @param elemento
	 * @param c
	 */
	protected void ubicarElemento(Posicionable elemento, Coordenada c) {

		int nroFila = c.getY();
		int nroColumna = c.getX();
		this.getCeldas().get(nroColumna).remove(nroFila);
		this.getCeldas().get(nroColumna).add(nroFila, elemento);

	}

	/**
	 * Este metodo genera una coordenada aleatoria dentro de los limites de la
	 * matriz.
	 * 
	 * @param ran
	 * @return Coordenada
	 */
	public Coordenada coordenadaAleatoria(Random ran) {

		int x = this.limite.getX();
		int y = this.limite.getY();

		int cx = ran.nextInt(x);
		int cy = ran.nextInt(y);

		Coordenada coord = new Coordenada(y, x);

		while (!enLimite(coord)) {
			cx = ran.nextInt(x);
			cy = ran.nextInt(y);
			coord = new Coordenada(cy, cx);
		}
		return coord;
	}

	/**
	 * Este metodo devuelve un booleano representado si la coordenada pasada por
	 * parametro esta o no dentro de los limites de la matriz.
	 * 
	 * @param coord
	 * @return boolean
	 */
	boolean enLimite(Coordenada coord) {

		return coord.getX() >= 0 && coord.getX() < limite.getX()
				&& coord.getY() >= 0 && coord.getY() < limite.getY();

	}

	/**
	 * Este metodo saca el elemento situado en una coordenada pasada por
	 * parametro
	 * 
	 * @param elemento
	 * @param c
	 */
	public void quitarElemento(Posicionable elemento) {

		int nroFila = elemento.getCoordenada().getY();
		int nroColumna = elemento.getCoordenada().getX();
		this.getCeldas().get(nroColumna).remove(nroFila);
		this.getCeldas().get(nroColumna).add(nroFila, new Celda());

	}

}
